home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / comm / bbs / Hydra11s.lha / HBBS / Source / Oberon / UserInfos.mod < prev    next >
Text File  |  1996-07-07  |  25KB  |  802 lines

  1. MODULE UserInfos;
  2.  
  3.     IMPORT
  4.     a:= Arguments, ac:= ANSIConsole, st:= Strings, cv:= Conversions, io, s:= SYSTEM,
  5.     e:= Exec, d:= Dos, ol:= OberonLib,
  6.     bo:= BBSColours, bs:= BBSStructures, bc:= BBSConstants,
  7.     hn:= HBBSNode, hc:= HBBSCommon, req:= Requests;
  8.  
  9.  
  10.     CONST EOF = -1; LF = 0AH;
  11.       LineLength = 80;
  12.       LTRUE = 1; LFALSE = 0;
  13.       NumericChars = "0123456789";
  14.  
  15.     TYPE
  16.     LineNodePtr = UNTRACED POINTER TO LineNode;
  17.     LineNode = STRUCT
  18.         prev, next: LineNodePtr;
  19.         text: ARRAY LineLength OF CHAR;
  20.     END;
  21.  
  22.     VAR
  23.     BBSGlobal: bs.BBSGlobalDataPtr;
  24.     NnD: bs.NodeDataPtr;
  25.     NodeNum: LONGINT;
  26.     argList: LineNodePtr;
  27.     CountArgs: INTEGER;
  28.     textPool: e.MemPoolPtr;
  29.     menuName: LineNodePtr;
  30.  
  31.     PROCEDURE cleanup(num: LONGINT);
  32.     BEGIN
  33.     IF hn.HBBSNodeBase # NIL THEN
  34.         hn.HBBSCleanUpDoor;
  35.         e.CloseLibrary(hn.HBBSNodeBase);
  36.         hn.HBBSNodeBase:= NIL;
  37.     END;
  38.     IF hc.HBBSCommonBase # NIL THEN
  39.         hc.HBBSCleanUpCommon;
  40.         e.CloseLibrary(hc.HBBSCommonBase);
  41.         hc.HBBSCommonBase:= NIL;
  42.     END;
  43.  
  44.     IF num # 0 THEN
  45.         io.WriteString("Door Error = ");
  46.         io.WriteInt(num, 0); io.WriteLn;
  47.          (* io.Format("Door Error = %d\n", s.ADR(num)) *)
  48.     END;
  49.     END cleanup;
  50.  
  51.     PROCEDURE init(name: e.STRPTR);
  52.     BEGIN
  53.     
  54.     IF hc.HBBSCommonBase = NIL THEN
  55.         cleanup(1); RETURN
  56.     END;
  57.     IF NOT hc.HBBSInitCommon() THEN
  58.         cleanup(2); RETURN
  59.     END;
  60.  
  61.     IF hn.HBBSNodeBase = NIL THEN
  62.         cleanup(3); RETURN
  63.     END;
  64.  
  65.     IF NOT hn.HBBSInitDoor(SHORT(NodeNum), name) THEN
  66.         cleanup(4); RETURN
  67.     END;
  68.  
  69.     END init;
  70.  
  71.     PROCEDURE AddNode(VAR list: LineNodePtr; at: INTEGER): LineNodePtr;
  72.     VAR last, new: LineNodePtr;
  73.         dummy: LineNode;
  74.     BEGIN
  75.     new:= e.AllocPooled(textPool, s.SIZE(dummy));
  76.     IF list = NIL THEN
  77.         IF new # NIL THEN
  78.         new^.prev:= NIL;
  79.         new^.next:= NIL;
  80.         END;
  81.         list:= new;
  82.     ELSE
  83.         IF at <= 1 THEN
  84.         IF new # NIL THEN
  85.             new^.prev:= NIL;
  86.             new^.next:= list;
  87.             list^.prev:= new;
  88.             list:= new;
  89.         END;
  90.         ELSE
  91.         last:= list;
  92.         WHILE (last^.next # NIL) & (at > 2) DO
  93.             last:= last^.next; at:= at - 1
  94.         END;
  95.         IF new # NIL THEN
  96.             new^.next:= last^.next;
  97.             new^.prev:= last;
  98.             IF last^.next # NIL THEN
  99.             last^.next^.prev:= new
  100.             END;
  101.             last^.next:= new;
  102.         END;
  103.         END;
  104.     END;
  105.     RETURN new;
  106.     END AddNode;
  107.  
  108.     PROCEDURE DeleteNode(VAR list: LineNodePtr; at: INTEGER);
  109.     VAR this: LineNodePtr;
  110.         dummy: LineNode;
  111.     BEGIN
  112.     IF list # NIL THEN
  113.         this:= list;
  114.         IF at <= 1 THEN
  115.         list:= this^.next;
  116.         IF list # NIL THEN list^.prev:= NIL END;
  117.         ELSE
  118.         WHILE (this^.next # NIL) & (at > 1) DO
  119.             this:= this^.next; at:= at - 1
  120.         END;
  121.         IF this^.prev # NIL THEN
  122.             this^.prev^.next:= this^.next
  123.         END;
  124.         IF this^.next # NIL THEN
  125.             this^.next^.prev:= this^.prev;
  126.         END;
  127.         END;
  128.         e.FreePooled(textPool, this, s.SIZE(dummy));
  129.     END;
  130.     END DeleteNode;
  131.  
  132.     PROCEDURE GetNode(list: LineNodePtr; at: INTEGER): LineNodePtr;
  133.     BEGIN
  134.     IF list = NIL THEN RETURN NIL END;
  135.     WHILE (list # NIL) & (at > 1) DO
  136.         list:= list^.next; at:= at - 1;
  137.     END;
  138.     RETURN list;
  139.     END GetNode;
  140.  
  141.     PROCEDURE ReqNumber(l: LONGINT);
  142.     VAR str: ARRAY 80 OF CHAR;
  143.         ok: BOOLEAN;
  144.         count: INTEGER; factor: LONGINT;
  145.     BEGIN
  146.     factor:= 1000000000; count:= 10;
  147.     WHILE (ABS(l) < factor) & (count > 1) DO count:= count - 1; factor:= factor DIV 10 END;
  148.     ok:= cv.IntToString(l, str, count);
  149.     IF ok THEN
  150.         req.BreakPoint(str)
  151.     END;
  152.     END ReqNumber;
  153.  
  154.     VAR str: ARRAY 80 OF CHAR;
  155.  
  156.     PROCEDURE PutNumber(l: LONGINT);
  157.     VAR ok: BOOLEAN;
  158.         count: INTEGER; factor: LONGINT;
  159.     BEGIN
  160.     factor:= 1000000000; count:= 10;
  161.     WHILE (ABS(l) < factor) & (count > 1) DO count:= count - 1; factor:= factor DIV 10 END;
  162.     ok:= cv.IntToString(l, str, count);
  163.     IF ok THEN
  164.         hn.DOORWriteText(s.ADR(str));
  165.     END;
  166.     END PutNumber;
  167.  
  168.     VAR str1: ARRAY 2 OF CHAR;
  169.  
  170.     PROCEDURE PutChar(ch: CHAR);
  171.     BEGIN
  172.     str1[0]:= ch; str1[1]:= CHR(0);
  173.     hn.DOORWriteText(s.ADR(str1));
  174.     END PutChar;
  175.  
  176.     PROCEDURE ReplyArgs;
  177.     VAR
  178.         i: INTEGER;
  179.         thisArg: LineNodePtr;
  180.     BEGIN
  181.     i:= 1;
  182.     LOOP
  183.         thisArg:= GetNode(argList, i);
  184.         IF thisArg # NIL THEN hn.DOORWriteText(s.ADR(thisArg^.text)) END; 
  185.         hn.DOORWriteText(s.ADR(" "));
  186.         IF thisArg = NIL THEN EXIT END;
  187.         i:= i + 1
  188.     END;
  189.     END ReplyArgs;
  190.  
  191.     VAR
  192.     sysopOptions, readOnly: BOOLEAN;
  193.     sysopFlag: LONGINT;
  194.     userData: bs.UserDataPtr;
  195.     dummyUser: bs.UserData;
  196.  
  197.     PROCEDURE GetStringAt(row, column: INTEGER; len, minlen: LONGINT; VAR str: ARRAY OF CHAR): BOOLEAN;
  198.     VAR res: LONGINT;
  199.     BEGIN
  200.     LOOP
  201.         ac.CURSORGoTo(PutChar, row, column);
  202.         ac.SetStyle(PutChar, ac.stBold); ac.SetColor(PutChar, ac.cForeWhite);
  203.         res:= hn.DOORGetLine(bc.GlDisplay + bc.GlNoOLM + bc.GlEdit + bc.GlNoDisturb + sysopFlag, CHR(0), len, 0, s.ADR(str));
  204.         IF (res = bc.InGotLine) THEN
  205.         IF st.Length(NnD^.CurrentLine^) >= minlen THEN
  206.             hc.strNcpy(s.ADR(str), NnD^.CurrentLine, SHORT(len));
  207.             RETURN TRUE;
  208.         END;
  209.         ELSE
  210.         RETURN FALSE
  211.         END;
  212.     END;
  213.     END GetStringAt;
  214.  
  215.     PROCEDURE GetNumberAt(row, column: INTEGER; len: INTEGER; VAR n: LONGINT): BOOLEAN;
  216.     VAR str: ARRAY 80 OF CHAR;
  217.         ok: BOOLEAN;
  218.     BEGIN
  219.     NnD^.CharsAllowed:= s.ADR(NumericChars);
  220.     cv.IntToStringLeft(n, str);
  221.     ok:= GetStringAt(row, column, len, 0, str);
  222.     NnD^.CharsAllowed:= NIL;
  223.     IF ok THEN
  224.         IF cv.StringToInt(str, n) THEN END;
  225.     END;
  226.     RETURN ok;
  227.     END GetNumberAt;
  228.  
  229.     PROCEDURE GetBoolAt(row, column: INTEGER; VAR b: LONGINT) : BOOLEAN;
  230.     VAR
  231.         res: LONGINT;
  232.     BEGIN
  233.     LOOP
  234.         ac.CURSORGoTo(PutChar, row, column);
  235.         ac.SetStyle(PutChar, ac.stBold); ac.SetColor(PutChar, ac.cForeWhite);
  236.         res:= hn.DOORGetLine(bc.GlNoOLM + bc.GlImmediate + bc.GlNoDisturb + sysopFlag, CHR(0), 1, 0, NIL);
  237.         IF (res = bc.InGotLine) OR (res = bc.InImmediate) THEN
  238.         hc.CVTUCase(NnD^.CurrentLine);
  239.         CASE NnD^.CurrentLine^[0] OF
  240.          "Y":
  241.             hn.DOORWriteText(s.ADR("Y"));
  242.             ac.SetStyle(PutChar, ac.stPlain);
  243.             hn.DOORWriteText(s.ADR("es"));
  244.             b:= bc.LTRUE; RETURN TRUE
  245.         |"N":
  246.             hn.DOORWriteText(s.ADR("N"));
  247.             ac.SetStyle(PutChar, ac.stPlain);
  248.             hn.DOORWriteText(s.ADR("o "));
  249.             b:= bc.LFALSE; RETURN TRUE
  250.         |CHR(0):
  251.             RETURN TRUE
  252.         ELSE
  253.         END;
  254.         ELSE
  255.         RETURN FALSE
  256.         END;
  257.     END;
  258.     END GetBoolAt;
  259.  
  260.     PROCEDURE GetPasswordAt(row, column: INTEGER; len, minlen: LONGINT; VAR str: ARRAY OF CHAR): BOOLEAN;
  261.     VAR res: LONGINT;
  262.     BEGIN
  263.     LOOP
  264.         ac.CURSORGoTo(PutChar, row, column);
  265.         ac.SetStyle(PutChar, ac.stBold); ac.SetColor(PutChar, ac.cForeWhite);
  266.         res:= hn.DOORGetLine(bc.GlDisplay + bc.GlNoOLM + bc.GlEdit + bc.GlNoDisturb + sysopFlag, "*", len, 0, s.ADR(str));
  267.         IF (res = bc.InGotLine) THEN
  268.         IF st.Length(NnD^.CurrentLine^) >= minlen THEN
  269.             hc.strNcpy(s.ADR(str), NnD^.CurrentLine, SHORT(len));
  270.             RETURN TRUE;
  271.         END;
  272.         ELSE
  273.         RETURN FALSE
  274.         END;
  275.     END;
  276.     END GetPasswordAt;
  277.  
  278.     PROCEDURE GetUserStateAt(row, column: INTEGER; VAR state: CHAR): BOOLEAN;
  279.  
  280.     PROCEDURE WriteState(s1, sz: ARRAY OF CHAR);
  281.     BEGIN
  282.         hn.DOORWriteText(s.ADR(s1));
  283.         ac.SetStyle(PutChar, ac.stPlain);
  284.         hn.DOORWriteText(s.ADR(sz));
  285.     END WriteState;
  286.  
  287.     VAR
  288.         res: LONGINT;
  289.     BEGIN
  290.     ac.CURSORGoTo(PutChar, row, column);
  291.     ac.SetStyle(PutChar, ac.stBold); ac.SetColor(PutChar, ac.cForeWhite);
  292.     LOOP
  293.         res:= hn.DOORGetLine(bc.GlNoOLM + bc.GlImmediate + bc.GlNoDisturb + sysopFlag, CHR(0), 1, 0, NIL);
  294.         IF (res = bc.InGotLine) OR (res = bc.InImmediate) THEN
  295.         hc.CVTUCase(NnD^.CurrentLine);
  296.         CASE NnD^.CurrentLine^[0] OF
  297.           bc.UserNew         : WriteState("N", "ew         "); EXIT;
  298.         | bc.UserValidated   : WriteState("V", "alidated   "); EXIT;
  299.         | bc.UserDeleted     : WriteState("D", "eleted     "); EXIT;
  300.         | bc.UserInactive    : WriteState("I", "nactive    "); EXIT;
  301.         | bc.UserLoginsDenied: WriteState("L", "ocked      "); EXIT;
  302.         | bc.UserOverwritable: WriteState("O", "verwritable"); EXIT;
  303.         | CHR(0)             : RETURN TRUE (* canceled *)
  304.         ELSE
  305.         END;
  306.         ELSE
  307.         RETURN FALSE
  308.         END;
  309.     END;
  310.     state:= NnD^.CurrentLine^[0];
  311.     RETURN TRUE;
  312.     END GetUserStateAt;
  313.  
  314.     PROCEDURE Pad(count: LONGINT; char: ARRAY OF CHAR);
  315.     BEGIN
  316.     WHILE count > 0 DO
  317.         hn.DOORWriteText(s.ADR(char));
  318.         DEC(count);
  319.     END;
  320.     END Pad;
  321.  
  322.     PROCEDURE GetListItemAt(row, column: INTEGER; list: e.ListPtr; listcount, offset: LONGINT; VAR index: LONGINT): BOOLEAN;
  323.  
  324.     VAR
  325.         res: LONGINT;
  326.         maxchars: LONGINT;
  327.         str, spaces: ARRAY 20 OF CHAR;
  328.         node: e.NodePtr;
  329.     BEGIN
  330.     cv.IntToStringLeft(index - offset, str);
  331.     ac.SetColor(PutChar, ac.cForeWhite);
  332.     maxchars:= 1;
  333.     IF listcount >= 10 THEN maxchars:= 2 END;
  334.     IF listcount >= 100 THEN maxchars:= 3 END;
  335.     IF listcount >= 1000 THEN maxchars:= 4 END;
  336.     NnD^.CharsAllowed:= s.ADR(NumericChars);
  337.     LOOP
  338.         ac.CURSORGoTo(PutChar, row, column);
  339.         ac.SetStyle(PutChar, ac.stBold);
  340.         res:= hn.DOORGetLine(bc.GlDisplay + bc.GlNoOLM + bc.GlImmediate + bc.GlNoDisturb + sysopFlag + bc.GlNoReturn, CHR(0), maxchars, 0, NIL);
  341.         IF (res = bc.InGotLine) OR (res = bc.InImmediate) THEN
  342.         hc.strNcpy(s.ADR(str), NnD^.CurrentLine, SHORT(maxchars));
  343. (*                IF st.Length(str) = 0 THEN
  344.             cv.IntToStringLeft(index, str);
  345.             hn.DOORWriteText(s.ADR(str));
  346.         END; *)
  347.         IF cv.StringToInt(str, index) THEN
  348.             ac.CURSORGoTo(PutChar, row, column);
  349.             cv.IntToStringLeft(index, str);
  350.             hn.DOORWriteText(s.ADR(str));
  351.             node:= hc.GetNode(list, SHORT(index));
  352.             IF (node # NIL) AND (index < listcount) THEN
  353.             Pad(maxchars - st.Length(str) + 1 , " ");
  354.             (*hn.DOORWriteText(s.ADR(" ")); *)
  355.             ac.SetStyle(PutChar, ac.stPlain);
  356.             spaces:= "                   "; (* fill chain with spaces *)
  357.             st.OverWrite(spaces, node^.name^, 0);
  358.             hn.DOORWriteText(s.ADR(spaces));
  359.             IF res = bc.InGotLine THEN
  360.                 index:= index + offset;
  361.                 RETURN TRUE
  362.             END;
  363.             END;
  364.         ELSE
  365.             hc.UpperCase(s.ADR(str));
  366.             IF st.Occurs(str, "N")>= 0 THEN
  367.             ac.CURSORGoTo(PutChar, row, column);
  368.             ac.SetStyle(PutChar, ac.stBold);
  369.             hn.DOORWriteText(s.ADR("?"));
  370.             ac.SetStyle(PutChar, ac.stPlain);
  371.             Pad(maxchars, " ");
  372.             hn.DOORWriteText(s.ADR("< none >            "));
  373.             index:= 0;
  374.             IF res = bc.InGotLine THEN RETURN TRUE END;
  375.             END;
  376.         END;
  377.         ELSE
  378.         RETURN FALSE
  379.         END;
  380.     END;
  381.     END GetListItemAt;
  382.  
  383.     PROCEDURE Enlight (check: BOOLEAN);
  384.     BEGIN
  385.     IF check THEN
  386.         ac.SetStyle(PutChar, ac.stBold); ac.SetColor(PutChar, ac.cForeWhite)
  387.     ELSE
  388.         ac.SetStyle(PutChar, ac.stPlain); ac.SetColor(PutChar, ac.cForeWhite)
  389.     END;
  390.     END Enlight;
  391.  
  392.     PROCEDURE WriteMask(str: e.STRPTR);
  393.     VAR s2: ARRAY 80 OF CHAR;
  394.         idx: INTEGER;
  395.     BEGIN
  396.     idx:= 0;
  397.     WHILE str^[idx] # CHR(0) DO s2[idx]:= "*"; INC(idx) END;
  398.     s2[idx]:= CHR(0);
  399.     hn.DOORWriteText(s.ADR(s2));
  400.     END WriteMask;
  401.  
  402.     PROCEDURE WriteNumber(n: LONGINT);
  403.     VAR s2: ARRAY 30 OF CHAR;
  404.     BEGIN
  405.     cv.IntToStringLeft(n, s2);
  406.     hn.DOORWriteText(s.ADR(s2));
  407.     END WriteNumber;
  408.  
  409.     PROCEDURE WriteState(ch: CHAR; canModify: BOOLEAN);
  410.     BEGIN
  411.     Enlight(canModify);
  412.     CASE ch OF
  413.       bc.UserNew: hn.DOORWriteText(s.ADR("N")); Enlight(FALSE); hn.DOORWriteText(s.ADR("ew"));
  414.     | bc.UserValidated: hn.DOORWriteText(s.ADR("V")); Enlight(FALSE); hn.DOORWriteText(s.ADR("alidated"));
  415.     | bc.UserInactive: hn.DOORWriteText(s.ADR("I")); Enlight(FALSE); hn.DOORWriteText(s.ADR("nactive"));
  416.     | bc.UserLoginsDenied: hn.DOORWriteText(s.ADR("L")); Enlight(FALSE); hn.DOORWriteText(s.ADR("ocked"));
  417.     | bc.UserOverwritable: hn.DOORWriteText(s.ADR("O")); Enlight(FALSE); hn.DOORWriteText(s.ADR("verwritable"));
  418.     ELSE
  419.         hn.DOORWriteText(s.ADR("?"));
  420.     END;
  421.     END WriteState;
  422.  
  423.     PROCEDURE WriteListItem(list: e.ListPtr; index, offset, count: LONGINT; canModify: BOOLEAN);
  424.     VAR s2: ARRAY 30 OF CHAR;
  425.         node: e.NodePtr;
  426.         spaces: LONGINT;
  427.     BEGIN
  428.     Enlight(canModify);
  429.     IF count < 10 THEN spaces:= 1
  430.     ELSIF count < 100 THEN spaces:= 2
  431.     ELSIF count < 1000 THEN spaces:= 3
  432.     ELSE spaces:= 4 END;
  433.     IF index < offset THEN
  434.         hn.DOORWriteText(s.ADR("?"));
  435.         Pad(spaces, " ");
  436.         Enlight(FALSE);
  437.         hn.DOORWriteText(s.ADR("< none >"));
  438.     ELSE
  439.         cv.IntToStringLeft(index - offset, s2); hn.DOORWriteText(s.ADR(s2));
  440.         node:= hc.GetNode(list, SHORT(index - offset));
  441.         IF node # NIL THEN
  442.         Enlight(FALSE); hn.DOORWriteText(s.ADR(" ")); hn.DOORWriteText(node^.name);
  443.         END;
  444.     END;
  445.     END WriteListItem;
  446.  
  447.     PROCEDURE WriteBool(b, canModify: BOOLEAN);
  448.     BEGIN
  449.     Enlight(canModify);
  450.     IF b THEN hn.DOORWriteText(s.ADR("Y")) ELSE hn.DOORWriteText(s.ADR("N")) END;
  451.     Enlight(FALSE);
  452.     IF b THEN hn.DOORWriteText(s.ADR("es")) ELSE hn.DOORWriteText(s.ADR("o")) END;
  453.     END WriteBool;
  454.  
  455.     PROCEDURE DisplayInfos(readOnly, sysopOptions: BOOLEAN);
  456.     BEGIN
  457.     ac.CURSORGoTo(PutChar, 3, 18);
  458.     Enlight((hn.HBBSCheckAccess(bc.AcsEditRealName) = bc.LTRUE) AND NOT readOnly);
  459.     hn.DOORWriteText(s.ADR(userData^.RealName));
  460.     ac.CURSORGoTo(PutChar, 4, 18);
  461.     Enlight((hn.HBBSCheckAccess(bc.AcsEditHandle) = bc.LTRUE) AND NOT readOnly);
  462.     hn.DOORWriteText(s.ADR(userData^.Handle));
  463.     ac.CURSORGoTo(PutChar, 4, 58);
  464.     Enlight((hn.HBBSCheckAccess(bc.AcsEditPassword) = bc.LTRUE) AND NOT readOnly);
  465.     IF sysopOptions THEN hn.DOORWriteText(s.ADR(userData^.Password[1]));
  466.     ELSE WriteMask(s.ADR(userData^.Password[1]));
  467.     END;
  468.     ac.CURSORGoTo(PutChar, 6, 18);
  469.     Enlight((hn.HBBSCheckAccess(bc.AcsEditGroup) = bc.LTRUE) AND NOT readOnly);
  470.     hn.DOORWriteText(s.ADR(userData^.Group[1]));
  471.     ac.CURSORGoTo(PutChar, 7, 18);
  472.     Enlight((hn.HBBSCheckAccess(bc.AcsEditCountry) = bc.LTRUE) AND NOT readOnly);
  473.     hn.DOORWriteText(s.ADR(userData^.Country[1]));
  474.     ac.CURSORGoTo(PutChar, 8, 18);
  475.     Enlight((hn.HBBSCheckAccess(bc.AcsEditComputer) = bc.LTRUE) AND NOT readOnly);
  476.     hn.DOORWriteText(s.ADR(userData^.ComputerType));
  477.     ac.CURSORGoTo(PutChar, 6, 58);
  478.     Enlight((hn.HBBSCheckAccess(bc.AcsEditLocation) = bc.LTRUE) AND NOT readOnly);
  479.     hn.DOORWriteText(s.ADR(userData^.GeoLocation));
  480.     ac.CURSORGoTo(PutChar, 7, 58);
  481.     Enlight((hn.HBBSCheckAccess(bc.AcsEditPhoneNumber) = bc.LTRUE) AND NOT readOnly);
  482.     hn.DOORWriteText(s.ADR(userData^.PhoneNumber));
  483.     ac.CURSORGoTo(PutChar, 8, 58);
  484.     Enlight(sysopOptions); WriteNumber(userData^.Access);
  485.     ac.CURSORGoTo(PutChar, 10, 18);
  486.     WriteState(userData^.Status, sysopOptions);
  487.     ac.CURSORGoTo(PutChar, 11, 18);
  488.     Enlight((hn.HBBSCheckAccess(bc.AcsEditLines) = bc.LTRUE) AND NOT readOnly);
  489.     WriteNumber(userData^.LinesPerScreen);
  490.     ac.CURSORGoTo(PutChar, 12, 18);
  491.     WriteListItem(BBSGlobal^.LanguageName, userData^.Language, 1, BBSGlobal^.Languages, (hn.HBBSCheckAccess(bc.AcsEditScreenType) = bc.LTRUE) AND NOT readOnly);
  492.     ac.CURSORGoTo(PutChar, 13, 18);
  493.     Enlight(sysopOptions); WriteNumber(userData^.TimeAllowed);
  494.     ac.CURSORGoTo(PutChar, 10, 58);
  495.     WriteListItem(BBSGlobal^.ConfList, userData^.PreferedConf, 1, BBSGlobal^.Conferences, NOT readOnly);
  496.     ac.CURSORGoTo(PutChar, 11, 58);
  497.     WriteListItem(BBSGlobal^.ProtocolList, userData^.Protocol, 1, BBSGlobal^.Protocols, (hn.HBBSCheckAccess(bc.AcsEditProtocol) = bc.LTRUE) AND NOT readOnly);
  498.     ac.CURSORGoTo(PutChar, 12, 58);
  499.     WriteBool(userData^.Editor = bc.LTRUE, (hn.HBBSCheckAccess(bc.AcsEditEditor) = bc.LTRUE) AND NOT readOnly);
  500.     ac.CURSORGoTo(PutChar, 13, 58);
  501.     WriteBool(userData^.UserType = bc.UserTypeExpert, NOT readOnly);
  502.     ac.CURSORGoTo(PutChar, 15, 18);
  503.     Enlight(sysopOptions); WriteNumber(userData^.FilesRatio);
  504.     IF userData^.FilesRatio = 0 THEN
  505.         Enlight(FALSE); hn.DOORWriteText(s.ADR(" disabled"));
  506.     END;
  507.     ac.CURSORGoTo(PutChar, 16, 18);
  508.     Enlight(sysopOptions); WriteNumber(userData^.UploadFiles);
  509.     ac.CURSORGoTo(PutChar, 17, 18);
  510.     Enlight(sysopOptions); WriteNumber(userData^.DownloadFiles);
  511.     ac.CURSORGoTo(PutChar, 15, 58);
  512.     Enlight(sysopOptions); WriteNumber(userData^.BytesRatio);
  513.     IF userData^.BytesRatio = 0 THEN
  514.         Enlight(FALSE); hn.DOORWriteText(s.ADR(" disabled"));
  515.     END;
  516.     ac.CURSORGoTo(PutChar, 16, 58);
  517.     Enlight(sysopOptions); WriteNumber(userData^.UploadFiles);
  518.     ac.CURSORGoTo(PutChar, 17, 58);
  519.     Enlight(sysopOptions); WriteNumber(userData^.UploadBytes);
  520.     ac.CURSORGoTo(PutChar, 19, 18);
  521.     Enlight(sysopOptions); WriteNumber(userData^.TimeUsed);
  522.     ac.CURSORGoTo(PutChar, 20, 18);
  523.     Enlight(sysopOptions); WriteNumber(userData^.MessagesWritten);
  524.     ac.CURSORGoTo(PutChar, 21, 18);
  525.     Enlight(sysopOptions); WriteNumber(userData^.BestCPSDown);
  526.     ac.CURSORGoTo(PutChar, 19, 58);
  527.     Enlight(sysopOptions); WriteNumber(userData^.CallsMade);
  528.     ac.CURSORGoTo(PutChar, 20, 58);
  529.     Enlight(sysopOptions); WriteNumber(userData^.PagesMade);
  530.     ac.CURSORGoTo(PutChar, 21, 58);
  531.     Enlight(sysopOptions); WriteNumber(userData^.BestCPSUp);
  532.     END DisplayInfos;
  533.  
  534.     PROCEDURE GetValue(option: CHAR; sysopOptions: BOOLEAN): BOOLEAN;
  535.     VAR ok: BOOLEAN;
  536.         expertMode: LONGINT;
  537.         tmpstr: ARRAY 80 OF CHAR;
  538.     BEGIN
  539.     ok:= TRUE;
  540.     CASE option OF
  541.       "A":
  542.         IF hn.HBBSCheckAccess(bc.AcsEditRealName) = bc.LTRUE THEN
  543.         ok:= GetStringAt(3, 18, 21, 1, userData^.RealName);
  544.         END;
  545.     | "B":
  546.         IF hn.HBBSCheckAccess(bc.AcsEditHandle) = bc.LTRUE THEN
  547.         ok:= GetStringAt(4, 18, 21, 1, userData^.Handle);
  548.         END;
  549.     | "C":
  550.         hc.StrFCpy(s.ADR(tmpstr), s.ADR(userData^.Password), 1);
  551.         IF sysopOptions THEN (* non masked password *)
  552.         ok:= GetStringAt(4, 58, bc.LenPassword, BBSGlobal^.MinPasswordLength, tmpstr);
  553.         ELSIF hn.HBBSCheckAccess(bc.AcsEditPassword) = bc.LTRUE THEN (* masked password *)
  554.         ok:= GetPasswordAt(4, 58, bc.LenPassword, BBSGlobal^.MinPasswordLength, tmpstr);
  555.         END;
  556.         hc.StrFCpy(s.ADR(userData^.Password[1]), s.ADR(tmpstr), 0);
  557.     | "D":
  558.         IF hn.HBBSCheckAccess(bc.AcsEditGroup) = bc.LTRUE THEN
  559.         hc.StrFCpy(s.ADR(tmpstr), s.ADR(userData^.Group), 1);
  560.         ok:= GetStringAt(6, 18, 21, 0, tmpstr);
  561.         hc.StrFCpy(s.ADR(userData^.Group[1]), s.ADR(tmpstr), 0);
  562.         END;
  563.     | "E":
  564.         IF hn.HBBSCheckAccess(bc.AcsEditCountry) = bc.LTRUE THEN
  565.         hc.StrFCpy(s.ADR(tmpstr), s.ADR(userData^.Country), 1);
  566.         ok:= GetStringAt(7, 18, bc.LenCountry, 0, tmpstr);
  567.         hc.StrFCpy(s.ADR(userData^.Country[1]), s.ADR(tmpstr), 0);
  568.         END;
  569.     | "F":
  570.         IF hn.HBBSCheckAccess(bc.AcsEditComputer) = bc.LTRUE THEN
  571.         ok:= GetStringAt(8, 18, 21, 0, userData^.ComputerType);
  572.         END;
  573.     | "G":
  574.         IF hn.HBBSCheckAccess(bc.AcsEditLocation) = bc.LTRUE THEN
  575.         ok:= GetStringAt(6, 58, bc.LenGeoLocation, 0, userData^.GeoLocation);
  576.         END;
  577.     | "H":
  578.         IF hn.HBBSCheckAccess(bc.AcsEditPhoneNumber) = bc.LTRUE THEN
  579.         ok:= GetStringAt(7, 58, bc.LenPhoneNumber, 0, userData^.PhoneNumber);
  580.         END;
  581.     | "I":
  582.         IF sysopOptions THEN ok:= GetNumberAt(8, 58, 4, userData^.Access) END;
  583.     | "J":
  584.         IF sysopOptions THEN ok:= GetUserStateAt(10, 18, userData^.Status) END;
  585.     | "K":
  586.         IF hn.HBBSCheckAccess(bc.AcsEditLines) = bc.LTRUE THEN
  587.         ok:= GetNumberAt(11, 18, 4, userData^.LinesPerScreen);
  588.         IF userData = s.ADR(NnD^.User.NormalData) THEN (* this is to fix a crash in FileLister *)
  589.             NnD^.User.CallData.LinesPerScreen:= userData^.LinesPerScreen
  590.         END;
  591.         END;
  592.     | "L":
  593.         IF hn.HBBSCheckAccess(bc.AcsEditScreenType) = bc.LTRUE THEN
  594.         ok:= GetListItemAt(12, 18, BBSGlobal^.LanguageName, BBSGlobal^.Languages, 1, userData^.Language);
  595.         END;
  596.     | "M":
  597.         IF sysopOptions THEN ok:= GetNumberAt(13, 18, 6, userData^.TimeAllowed) END;
  598.     | "N":
  599.         (* always dispo *)
  600.         ok:= GetListItemAt(10, 58, BBSGlobal^.ConfList, BBSGlobal^.Conferences, 1, userData^.PreferedConf);
  601.     | "O":
  602.         IF hn.HBBSCheckAccess(bc.AcsEditProtocol) = bc.LTRUE THEN
  603.         ok:= GetListItemAt(11, 58, BBSGlobal^.ProtocolList, BBSGlobal^.Protocols, 1, userData^.Protocol);
  604.         END;
  605.     | "P":
  606.         IF hn.HBBSCheckAccess(bc.AcsEditEditor) = bc.LTRUE THEN
  607.         ok:= GetBoolAt(12, 58, userData^.Editor);
  608.         END;
  609.     | "Q":
  610.         (* always dispo *)
  611.         IF userData^.UserType = bc.UserTypeExpert THEN expertMode:= bc.LTRUE ELSE expertMode:= bc.LFALSE END;
  612.         ok:= GetBoolAt(13, 58, expertMode);
  613.         IF expertMode = bc.LTRUE THEN userData^.UserType:= bc.UserTypeExpert ELSE userData^.UserType:= bc.UserTypeNormal END;
  614.     | "R":
  615.         IF sysopOptions THEN
  616.         ok:= GetNumberAt(15, 18, 1, userData^.FilesRatio);
  617.         IF userData^.FilesRatio = 0 THEN
  618.             ac.CURSORGoTo(PutChar, 15, 20);
  619.             ac.SetStyle(PutChar, ac.stPlain); ac.SetColor(PutChar, ac.cForeWhite);
  620.             hn.DOORWriteText(s.ADR("disabled"));
  621.         END;
  622.         END;
  623.     | "S":
  624.         IF sysopOptions THEN
  625.         ok:= GetNumberAt(16, 18, 20, userData^.UploadFiles);
  626.         END;
  627.     | "T":
  628.         IF sysopOptions THEN
  629.         ok:= GetNumberAt(17, 18, 20, userData^.DownloadFiles);
  630.         END;
  631.     | "U":
  632.         IF sysopOptions THEN
  633.         ok:= GetNumberAt(15, 58, 1, userData^.BytesRatio);
  634.         IF userData^.BytesRatio = 0 THEN
  635.             ac.CURSORGoTo(PutChar, 15, 60);
  636.             ac.SetStyle(PutChar, ac.stPlain); ac.SetColor(PutChar, ac.cForeWhite);
  637.             hn.DOORWriteText(s.ADR("disabled"));
  638.         END;
  639.         END;
  640.     | "V":
  641.         IF sysopOptions THEN
  642.         ok:= GetNumberAt(16, 58, 20, userData^.UploadBytes);
  643.         END;
  644.     | "W":
  645.         IF sysopOptions THEN
  646.         ok:= GetNumberAt(17, 58, 20, userData^.DownloadBytes);
  647.         END;
  648.     | "0":
  649.         IF sysopOptions THEN
  650.         ok:= GetNumberAt(19, 18, 4, userData^.TimeUsed);
  651.         END;
  652.     | "1":
  653.         IF sysopOptions THEN
  654.         ok:= GetNumberAt(20, 18, 20, userData^.MessagesWritten);
  655.         END;
  656.     | "2":
  657.         IF sysopOptions THEN
  658.         ok:= GetNumberAt(21, 18, 20, userData^.BestCPSDown);
  659.         END;
  660.     | "3":
  661.         IF sysopOptions THEN
  662.         ok:= GetNumberAt(19, 58, 20, userData^.CallsMade);
  663.         END;
  664.     | "4":
  665.         IF sysopOptions THEN
  666.         ok:= GetNumberAt(20, 58, 20, userData^.PagesMade);
  667.         END;
  668.     | "5":
  669.         IF sysopOptions THEN
  670.         ok:= GetNumberAt(21, 58, 20, userData^.BestCPSUp);
  671.         END;
  672.     | "?":
  673.         IF hn.DOORDisplaySpecialScreen(s.ADR("USERINFOHELP")) = e.LTRUE THEN END;
  674.         IF hn.DOORDisplaySpecialScreen(s.ADR("USERINFOS")) = e.LTRUE THEN END;
  675.         DisplayInfos(readOnly, sysopOptions);
  676.     ELSE
  677.     END;
  678.     RETURN ok;
  679.     END GetValue;
  680.  
  681.     PROCEDURE DoorMain;
  682.     VAR
  683.         iStart, iEnd: LONGINT;
  684.         arg: LineNodePtr;
  685.         myself, userID: LONGINT;
  686.         sUserID: ARRAY 10 OF CHAR;
  687.         option: CHAR;
  688.         res: LONGINT;
  689.         so: BOOLEAN;
  690.     BEGIN
  691.     IF NnD^.NodeDevice.SysopNode = bc.LTRUE THEN sysopFlag:= bc.GlSysop ELSE sysopFlag:= 0 END;
  692.     so:= st.Occurs(NnD^.ActiveDoor^.SystemOptions^, "SYSOP") >= 0;
  693.     myself:= NnD^.User.CallData.UserID; userID:= myself;
  694.     IF CountArgs > 1 THEN
  695.         arg:= GetNode(argList, 2);
  696.         IF arg # NIL THEN
  697.         iStart:= st.Occurs(arg^.text,"USERID=");
  698.         hc.StrFCpy(s.ADR(sUserID), s.ADR(arg^.text), SHORT(iStart + 7));
  699.         IF NOT cv.StringToInt(sUserID, userID) THEN END;
  700.         END;
  701.     END;
  702.     readOnly:= (userID # myself) AND NOT so;
  703.     (* allow user to view friend's account, but not to modify *)
  704.     (* so:= sysopOptions; *)
  705.  
  706.     IF userID # myself THEN (* user is not online *)
  707.         IF NOT hc.HBBSLoadUser(userID, NIL, NIL, s.VAL(bs.UserDataPtr, s.ADR(dummyUser))) THEN RETURN END;
  708.         userData:= s.VAL(bs.UserDataPtr, s.ADR(dummyUser));
  709.     ELSE  (* user is online, change take effect immediatly *)
  710.         userData:= s.VAL(bs.UserDataPtr, s.ADR(NnD^.User.NormalData));
  711.     END;
  712.  
  713.     IF NOT(hn.DOORDisplaySpecialScreen(s.ADR("USERINFOS")) = bc.LTRUE) THEN RETURN END;
  714.  
  715.     DisplayInfos(readOnly, so);
  716.     (* sysopOptions:= so; *)
  717.  
  718.     LOOP
  719.         ac.CURSORGoTo(PutChar, 22, 2);
  720.         res:= hn.DOORGetLine(bc.GlImmediate + bc.GlNoOLM + bc.GlNoDisturb + sysopFlag, CHR(0), 1, 0, NIL);
  721.         IF (res = bc.InGotLine) THEN
  722.         option:= NnD^.CurrentLine^[0];
  723.         IF option = CHR(0) THEN EXIT END;
  724.         IF NOT readOnly THEN
  725.             IF (option >="a") AND (option <="z") THEN
  726.             option:= CHR(ORD(option) - 32);
  727.             END;
  728.             IF NOT GetValue(option, so) THEN RETURN END;
  729.         END;
  730.         ELSE
  731.         EXIT
  732.         END;
  733.     END;
  734.  
  735.     IF NOT readOnly THEN
  736.         ac.CURSORGoTo(PutChar, 22, 2);
  737.         IF userID # myself THEN
  738.         hn.DOORWriteText(s.ADR("Updating user..."));
  739.         ELSE
  740.         hn.DOORWriteText(s.ADR("Updating your data..."));
  741.         END;
  742.         hc.HBBSSaveUserData(userData);
  743.         hn.HBBSSetAccess;
  744.         hn.DOORWriteText(s.ADR("Ok"));
  745.     END;
  746.  
  747.     END DoorMain;
  748.  
  749.     PROCEDURE ParseArgs;
  750.     VAR
  751.         i: INTEGER;
  752.         newArg: LineNodePtr;
  753.         s: ARRAY 80 OF CHAR;
  754.         ok: BOOLEAN;
  755.     BEGIN
  756.     CountArgs:= a.NumArgs();
  757.     i:= 1;
  758.     WHILE i <= CountArgs DO
  759.         newArg:= AddNode(argList, MAX(INTEGER));
  760.         IF newArg # NIL THEN
  761.         a.GetArg(i, newArg^.text);
  762.         ELSE
  763.         CountArgs:= i;
  764.         END;
  765.         i:= i + 1
  766.     END;
  767.     END ParseArgs;
  768.  
  769.  
  770.     VAR
  771.     newArg: LineNodePtr;
  772.     dummy: LineNode;
  773.  
  774. BEGIN
  775.     textPool:= e.CreatePool(LONGSET{}, s.SIZE(dummy), s.SIZE(dummy));
  776.     ParseArgs;
  777.     IF CountArgs > 0 THEN
  778.      newArg:= GetNode(argList, 1);
  779.      IF cv.StringToInt(newArg^.text, NodeNum) THEN
  780.         init(s.ADR("UserInfos Menu"));
  781.         IF hc.HBBSCommonBase # NIL THEN
  782.         BBSGlobal:= hc.HBBSGimmeBBS();
  783.         IF BBSGlobal # NIL THEN
  784.             NnD:= hc.HBBSNodeDataPtr(SHORT(NodeNum));
  785.             IF NnD # NIL THEN
  786.             DoorMain;
  787.             END;
  788.         END;
  789.         END;
  790.         cleanup(0);
  791.     ELSE
  792.         io.WriteString("Invalid Param for door!\n")
  793.     END;
  794.     ELSE
  795.     io.WriteString("No Param for door!\n");
  796.     END;
  797. CLOSE
  798.     cleanup(0);
  799.     e.DeletePool(textPool);
  800. END UserInfos.
  801.  
  802.